package scalab.core.gates

import component.{ExecutableComponent, Component, SinkComponent}
import dependencies.Dependency

trait Output extends Provider{
	final def output: Output = this

//  import scala.collection.Set
	import scala.collection.immutable.{Set,HashSet}

	//protected[core] and define getter for public usage...
	def productDependencies: Set[Dependency] = deps //name it products
	private[scalab] def setDeps(newDeps: Set[Dependency]): Unit = {//change this to setProductDependencies
		deps = newDeps
	}
	//add def addProductDependencies..
  protected var deps: Set[Dependency] = 
		HashSet.empty[Dependency]

	def computeComponentId: String = {
		component.updateId
		component.id
	}

	//implement later...
	/*override def upToDate: Boolean = component.upToDate
	private[core] def upToDate(fresh: List[Buildable]): Pair[Boolean, List[Buildable]] = 
		component upToDate fresh
	private[core] def locallyUpToDate: Boolean = component.locallyUpToDate*/

	private[core] def update(
		visited: Set[Component], 
		cycles: Set[(Output, Input)], 
		fresh: Set[ExecutableComponent]): (
			Boolean, 
			Set[Component], 
			Set[(Output, Input)], 
			Set[ExecutableComponent]
		) = {
			fireUpdateStarted
			val res = component.update(visited, cycles, fresh)
			fireUpdateFinished(res._1)
			res
		}

	private[core] def upToDate(
		products: Set[Resource],
		visited: Set[Component], 
		cycles: Set[(Output, Input)], 
		fresh: Set[ExecutableComponent]): (
			Boolean, 
			Set[Component], 
			Set[(Output, Input)], 
			Set[ExecutableComponent]
		) = component.upToDate(products, visited, cycles, fresh)

	private[core] def validate(
		visited: Set[Component], 
		cycles: Set[(Output, Input)], 
		validated: Set[SinkComponent]): (
			Boolean, 
			Set[Component], 
			Set[(Output, Input)], 
			Set[SinkComponent]
		) = component.validate(visited, cycles, validated) 

	/*private[core] def validate(validated: Set[Buildable]): Pair[Boolean, Set[Buildable]] = 
		component.validate(validated)*/
}
